<template>
  <div :class="getClassName" v-bind="$attrs" v-if="isEdit">
    <Spin :spinning="spinning" size="large" :delay="200">
      <div class="h-100vh">
        <div class="title h-14 px-4 flex items-center">
          <div class="back w-66 overflow-hidden">
            <span @click="handleClose()">
              <Icon icon="iconoir:nav-arrow-left" size="18" class="cursor-pointer mr-1.5" />
              <span class="cursor-pointer text">
                <span class="mr-1.5 align-text-bottom">{{ formInfo.modelName }}</span>
                <!-- @click="handleOpenBasicInfo()" -->
                <!-- <Icon icon="icon-park-outline:setting-one" size="18" /> -->
              </span>
            </span>
          </div>
          <div class="left-btn-box">
            <template v-for="item in clientList" :key="item.value">
              <div
                :class="{
                  active: item['intValue'] === formInfo.client,
                  btn: true,
                  create: true,
                }"
                @click="handleChangeClient(item['intValue'])"
              >
                <Icon :icon="iconMap[item.label]" size="16" />
                <span class="ml-0.5" v-if="item['intValue'] === formInfo.client">{{
                  item.description
                }}</span>
              </div>
            </template>
          </div>
          <div class="tabs flex justify-center flex-1">
            <div class="tabs-conent flex space-x-2">
              <div
                v-for="item in tabList"
                :key="item.value"
                :class="['tab', tabRef == item.value && 'active']"
                @click="changeTab(item.value)"
              >
                {{ item.label }}
              </div>
            </div>
          </div>
          <div class="actions flex mr-2 space-x-2">
            <div class="label" @click="handleSumbit(true)">
              <Icon icon="back|svg" size="18" />
              <span class="align-text-bottom ml-1.5">保存并返回</span>
            </div>
            <div class="label" @click="handleSumbit()">
              <Icon icon="icon-park-outline:save" size="18" />
              <span class="align-text-bottom ml-1.5">保存</span>
            </div>
            <div class="label" @click="handlePreview()">
              <Icon icon="uiw:eye-o" size="18" class="align-text-bottom" />
              <span class="align-text-bottom ml-1.5">预览</span>
            </div>
          </div>
        </div>

        <div v-if="isLoad" class="config-body h-[calc(100%-3.5rem)]">
          <DataInfoTable :data="formInfo" v-show="tabRef === 0" />
          <FormDesign
            ref="formDesignRef"
            :isCreate="isCreate"
            v-show="tabRef === 1"
            :data="formInfo"
          />
          <BasicInfo
            ref="basicRef"
            :isDetail="!!modelConfig.modelId"
            :data="formInfo"
            v-show="tabRef === 2"
          />
        </div>
        <Spin v-else wrapperClassName="h-full">
          <HEmpty class="mt-10" />
        </Spin>
      </div>
    </Spin>
  </div>
  <BasicInfoModal
    @register="registerBasic"
    @cancel="handleCancelBasicInfo"
    @success="handleBasicInfo"
  />
  <PreviewModal @register="registerPreview" />
</template>

<script lang="ts" setup name="FormDesignContainer">
  import { ref, computed, onBeforeMount } from 'vue';
  import { Spin } from 'ant-design-vue';
  import { ModelFormConfig } from './typing';
  import { useDesign } from '/@/hooks/web/useDesign';
  import { useMessage } from '/@/hooks/web/useMessage';
  import { useModal } from '/@/components/Modal';
  import BasicInfoModal from './BasicInfoModal.vue';
  import PreviewModal from './PreviewModal.vue';
  import BasicInfo from './BasicInfo.vue';
  import DataInfoTable from './DataInfoTable.vue';
  import FormDesign from './form-design/components/VFormDesign/index.vue';
  import HEmpty from '/@/components/HEmpty/index.vue';
  import Icon from '/@/components/Icon/index';
  import { DICT } from '/@/enums/dict';
  import { getDictTypeListApi } from '/@/api/admin/dict';
  import { useFormDesignStoreWithOut } from '/@/store/modules/formDesign';
  import {
    MODEL_TYPE,
    getModelInfoApi,
    saveModelApi,
    updateModelApi,
    // getFieldsFromDbListApi,
    // getFieldsFromTableDefineListApi,
  } from '/@/api/config-center/model-design';
  const formDesignStore = useFormDesignStoreWithOut();
  const { prefixCls } = useDesign('FormDesignContainer');
  const { createMessage } = useMessage();
  const iconMap = {
    PC: 'computer|svg',
    APP: 'phone|svg',
  };
  const props = withDefaults(
    defineProps<{
      modelConfig: Indexable;
    }>(),
    {
      modelConfig: () => ({}),
    },
  );
  const emit = defineEmits(['update:visble', 'change', 'success']);
  const [registerBasic, { openModal: basicModal }] = useModal();

  const spinning = ref(true);
  const isCreate = ref(true);
  const isEdit = ref(false);
  const isLoad = ref(false);
  const formDesignRef = ref();
  const basicRef = ref();
  const clientList = ref<any[]>([]);

  const getClassName = computed(() => {
    return [prefixCls, `${prefixCls}_fixed`];
  });

  // 提交存储 后端给什么就提交什么
  let baseObj: ModelFormConfig = {
    modelName: '',
    modelCode: '',
    modelType: '',
    client: 0,
    classify: MODEL_TYPE.FORM,
    dataInfo: {},
    // @ts-ignore
    formDesignInfo: {
      // colSpan: 23,
      labelAlign: 'right',
      layout: 'horizontal',
      event: {},
      schemas: {
        0: [],
        1: [],
        2: [],
      },
      btns: [],
      modifyLogConfig: {},
    },
  };

  const tabRef = ref(1);
  const tabList = [
    {
      label: '表单设计',
      value: 1,
    },
    {
      label: '数据模型',
      value: 0,
    },
    {
      label: '基本信息',
      value: 2,
    },
  ];

  async function changeTab(key) {
    if (tabRef.value === key) {
      return;
    }
    try {
      // 当在表单设计页面时校验当前控件
      if (tabRef.value === 1) {
        await formDesignRef.value.currentFormValidate();
      }
      tabRef.value = key;
    } catch (e) {
      throw e;
    }
  }

  async function getClients() {
    const ret = await getDictTypeListApi({
      type: DICT.CLIENT_TYPE,
    });
    clientList.value = ret;
  }

  onBeforeMount(async () => {
    try {
      await getClients();

      const { modelId } = props.modelConfig || {};

      //  有id则为编辑
      if (modelId) {
        isCreate.value = false;
        isEdit.value = true;
        init(modelId);
        return;
      }

      handleOpenBasicInfo();
    } catch (e) {
      throw e;
    } finally {
      spinning.value = false;
    }
  });
  const formInfo = ref<ModelFormConfig>(baseObj);

  async function init(modelId) {
    const data = await getModelInfoApi<ModelFormConfig>(modelId as string);

    if (data.modules) {
      data.modules = undefined;
    }
    // clientList.value

    if (!data.formDesignInfo.schemas[1]) {
      data.formDesignInfo.schemas[1] = [];
    }
    //@ts-ignore
    formInfo.value = data;

    baseObj = data;

    isLoad.value = true;
  }

  function handleChangeClient(val) {
    //  兼容处理
    if (!formInfo.value.formDesignInfo.schemas[val]) {
      formInfo.value.formDesignInfo.schemas[val] = [];
    }

    formInfo.value.client = val;
  }

  function handleOpenBasicInfo() {
    basicModal(true, {
      isDetail: !!props.modelConfig.modelId,
      info: formInfo.value,
    });
  }
  function handleBasicInfo({ isUpdate, data }) {
    formInfo.value = {
      ...baseObj,
      ...data,
    };
    if (isUpdate) {
      return;
    }
    isEdit.value = true;
    isLoad.value = true;
  }
  function handleCancelBasicInfo() {
    if (props.modelConfig.modelId || isEdit.value) return;
    handleClose();
    isEdit.value = false;
    isLoad.value = false;
  }

  async function handleSumbit(flag = false) {
    let isError = true;
    const prefixErrorTip = '表单设计 — ';
    try {
      if (formDesignStore.getFormPropsRef) {
        await formDesignStore.getFormPropsRef.validate();
        isError = false;
      }
    } catch (e: any) {
      const text = prefixErrorTip + '表单属性校验失败：' + e.errorFields[0].errors;
      createMessage.error(text);
      throw e;
    }
    await formDesignRef.value.currentFormValidate();

    try {
      if (isError) return;
      spinning.value = true;

      await formValidate();

      const ajaxFn = props.modelConfig.modelId ? updateModelApi : saveModelApi;
      formInfo.value.formDesignInfo.client = formInfo.value.client || 0;
      await ajaxFn(formInfo.value as ModelFormConfig);
      if (flag) {
        handleClose(true);
      } else {
        createMessage.success('操作成功');
      }
    } catch (e: any) {
      e.errorFields && createMessage.error(e.errorFields[0].errors);
      throw e;
    } finally {
      spinning.value = false;
    }
  }

  async function formValidate() {
    const data = await basicRef.value.getBasicVal();
    formInfo.value = Object.assign(formInfo.value, data);
    console.log(
      '%cformInfo.value.formDesignInfo.schemas;===>251： ',
      'background: rgb(23, 197, 237,.6); color: #ff5023; font-size:18px;font-weight:700',
      formInfo.value,
    );
  }

  const [registerPreview, { openModal: previewModal }] = useModal();

  function handlePreview() {
    previewModal(true, formInfo.value);
  }
  function handleClose(flag = false) {
    if (flag) {
      createMessage.success('操作成功');
    }
    emit('change', flag);
    spinning.value = false;
  }
</script>
<style lang="less" scoped>
  @prefix-cls: ~'@{namespace}-FormDesignContainer';
  @color-primary: #2b63a1;
  @title-text-color: #fff;
  @primary-background-color: fade(@color-primary, 100%);
  .@{prefix-cls} {
    z-index: 700;
    color: #333;
    background-color: @component-background;

    &_fixed {
      position: fixed;
      left: 0;
      right: 0;
      top: 0;
      bottom: 0;
    }

    .title {
      background: #f4f6f9;

      .text:hover {
        color: @color-primary;
      }
    }

    .tabs-conent {
      .tab {
        width: 98px;
        height: 34px;
        line-height: 34px;
        text-align: center;
        font-size: 14px;
        color: @color-primary;
        border-radius: 20px;
        transition: all 0.3s;
        cursor: pointer;

        &.active {
          background: @color-primary;
          color: #fff;
        }

        &:hover {
          .active();
        }
      }
    }

    .left-btn-box {
      height: 36px;
      display: flex;
      align-items: center;
      justify-content: center;
      border-radius: 4px;
      background-color: rgba(43, 98, 161, 0.05);

      .btn {
        padding: 0 12px;
        height: 28px;
        line-height: 28px;
        text-align: center;
        margin-left: 1px;
        transition: background ease 0.3s;
        font-size: 14px;

        &.active {
          color: @title-text-color;
          border-radius: 4px;
          background-color: @primary-background-color;
        }

        &.create {
          cursor: pointer;

          &:hover {
            .active();
          }
        }
      }
    }

    .actions {
      .label {
        padding: 10px 16px;
        cursor: pointer;
        font-size: 14px;
        font-weight: 600;
        color: @color-primary;

        &:hover {
          background: rgba(52, 66, 83, 0.05);
          border-radius: 4px;
        }
      }
    }
  }
</style>
